using System;
using DslCrossModelFramework;
using DslCrossModelFramework.NameResolution;
using Microsoft.VisualStudio.Modeling;
using Xunit;

namespace UnitTest.xUnitTests.CrossModelFramework {
    public class NameResolutionTests {

        [Fact]
        public void DefaultNameResolverTest() {
            TestHelper.RegisterEnvironmentConfiguration();
            IModelDirectory modelDirectory = TestHelper.GetModelDirectory();
            modelDirectory.PreloadAllModelFiles();
            foreach (ModelElement mel in modelDirectory.AllElements()) {
                var nameResolver = new DefaultModelElementNameResolver();
                string name = nameResolver.GetModelElementName(mel);
                Assert.False(string.IsNullOrEmpty(name));
            }
        }

        [Fact]
        public void DefaultNameResolverScopeTest() {
            TestHelper.ResetEnvironment();
            IModelDirectory modelDirectory = TestHelper.GetModelDirectory();
            modelDirectory.PreloadAllModelFiles();
            foreach (ModelElement mel in modelDirectory.AllElements()) {
                IModelElementNameResolver nameResolver = NameResolutionManager.Current.GetResolver(mel.GetDomainClass());
                string defaultName = nameResolver.GetName(mel);
                string actualName = NameResolutionManager.Current.GetElementName(mel, "FooBar");
                Assert.Equal(defaultName, actualName);
            }
        }

        [Fact]
        public void UnScopedNameResolverRegistrationTest() {
            TestHelper.ResetEnvironment();
            IModelDirectory modelDirectory = TestHelper.GetModelDirectory();
            modelDirectory.PreloadAllModelFiles();
            bool foundCustomNameResolver = false;
            foreach (ModelElement mel in modelDirectory.AllElements()) {
                Type nameResolverType = typeof(DefaultModelElementNameResolver);
                foreach (object attribute in mel.GetDomainClass().ImplementationClass.GetCustomAttributes(true)) {
                    if (attribute is ModelElementNameResolutionAttribute && string.IsNullOrEmpty(((ModelElementNameResolutionAttribute)attribute).Scope)) {
                        nameResolverType = ((ModelElementNameResolutionAttribute)attribute).NameResolver;
                        foundCustomNameResolver = true;
                    }
                }
                string expectedName = ((IModelElementNameResolver)nameResolverType.GetConstructor(new Type[] { }).Invoke(null)).GetName(mel);
                string actualName = NameResolutionManager.Current.GetElementName(mel);

                Assert.Equal(expectedName, actualName);
            }

            if (!foundCustomNameResolver) {
                Assert.False(true, "No custom name resolvers have been defined on any model element types");
            }
        }
    }
}